home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 1.iso / ARGONET / PD / PROGRAMMING / DESKLIBC / SOURCES.ZIP / DeskLib / !DLSources / Libraries / Dialog2 / c / OpenClose < prev    next >
Text File  |  1995-07-15  |  9KB  |  353 lines

  1. /*
  2.     ####             #    #     # #
  3.     #   #            #    #       #          The FreeWare C library for
  4.     #   #  ##   ###  #  # #     # ###             RISC OS machines
  5.     #   # #  # #     # #  #     # #  #   ___________________________________
  6.     #   # ####  ###  ##   #     # #  #
  7.     #   # #        # # #  #     # #  #    Please refer to the accompanying
  8.     ####   ### ####  #  # ##### # ###    documentation for conditions of use
  9.     ________________________________________________________________________
  10.  
  11.     File:    Dialog2.OpenClose.c
  12.     Author:  Copyright © 1994 Julian Smith
  13.     Version: 1.03 (13 Mar 1995)
  14.     Purpose: Dialogue box handling
  15. */
  16.  
  17.  
  18. #include <stdlib.h>
  19.  
  20. #include "DeskLib:Window.h"
  21. #include "DeskLib:WimpSWIs.h"
  22. #include "DeskLib:Event.h"
  23. #include "DeskLib:Error.h"
  24. #include "DeskLib:Handler.h"
  25. #include "DeskLib:Sound.h"
  26. #include "DeskLib:Template.h"
  27. #include "DeskLib:Dialog2.h"
  28.  
  29. #include "Defs.h"
  30.  
  31.  
  32. /*
  33. We don't use _DeskLib_SDLS_staticglobal because dialog2_menublock is used by other
  34. files within the Dialog2 library.
  35. */
  36. dialog2_block    *dialog2_menublock = NULL;
  37.  
  38.  
  39. #ifdef _DLL
  40. dialog2_block    **Dialog2__Ref_menublock( void)    { return &dialog2_menublock;    }
  41. #endif
  42.  
  43.  
  44. static void    Dialog2__ClaimOrReleaseStandardHandlers(
  45.     event_claimorreleasefn    fn, 
  46.     dialog2_block        *dialog2
  47.     );
  48.     /* The actual function is later on...    */
  49.  
  50.  
  51.  
  52.  
  53.  
  54. BOOL    Dialog2__CloseDialogInternal( 
  55.     dialog2_block    *dialog2, 
  56.     BOOL        closemenu,    /* If TRUE, close the current menu if dialog is a menu    */
  57.     BOOL        deletewindow    /* If TRUE, delete the window if dialog2 allows.    */
  58.     )
  59. {
  60. if ( !dialog2)    return ERROR;
  61. if ( dialog2->flags.data.type == dialog2_type_CLOSED)    return ERROR;
  62.  
  63. if ( dialog2->window)    {
  64.  
  65.     Dialog2__ClaimOrReleaseStandardHandlers( Event_Release, dialog2);
  66.  
  67.     if (       dialog2->flags.data.type == dialog2_type_MENU
  68.         || dialog2->flags.data.type == dialog2_type_MENULEAF
  69.         )
  70.         {
  71.         if (closemenu)    Wimp_CreateMenu( (menu_block *) -1, 0, 0);
  72.         }
  73.     else    Wimp_CloseWindow( dialog2->window);
  74.     
  75.     if ( !dialog2->flags.data.keepwindow)    {
  76.         if ( deletewindow)    {
  77.             Window_Delete( dialog2->window);
  78.             dialog2->window = NULL;
  79.             }
  80.         else    Event_ReleaseWindow( dialog2->window);
  81.         }
  82.     }
  83.  
  84. dialog2->flags.data.type = dialog2_type_CLOSED;
  85.  
  86. if ( dialog2->flags.data.notifyclose && dialog2->openfn)
  87.     dialog2->openfn( dialog2);
  88.  
  89. if ( dialog2_menublock == dialog2)    dialog2_menublock = NULL;
  90.     /* So we know whether a menu-dialog2 is open.    */
  91.  
  92. return NOERROR;
  93. }
  94.  
  95.  
  96.  
  97.  
  98. BOOL    Dialog2_CloseDialog( dialog2_block *dialog2)
  99. {
  100. return Dialog2__CloseDialogInternal( 
  101.     dialog2, 
  102.     TRUE,    /* close menu if dialog2 is part of a menu;        */
  103.     TRUE    /* delete window if !dialog2->flags.data.keepwindow    */
  104.     );
  105. }
  106.  
  107.  
  108.  
  109.  
  110. _DeskLib_SDLS_PtrFn( 
  111.     static,
  112.     BOOL, 
  113.     Dialog2__MenusDeletedHandler( event_pollblock *event, void *reference)
  114.     )
  115. /* static BOOL    Dialog2__MenusDeletedHandler( event_pollblock *event, void *reference)*/
  116. /* Handler for message_MENUSDELETED - sent if the menu closes.    */
  117. /* cc warns about extern ... not declared in header in SDLS compiles    */
  118. {
  119. UNUSED( reference);
  120.  
  121. if ( event->data.message.header.action == message_MENUSDELETED && dialog2_menublock)    {
  122.     
  123.     if    ( 
  124.         dialog2_menublock->flags.data.type == dialog2_type_MENU
  125.         &&
  126.         (window_handle) event->data.message.data.words[0] != dialog2_menublock->window
  127.         )
  128.         return FALSE;
  129.         /* The menu being deleted isn't our dialog2 box - eg the user    */
  130.         /* has opened the dialog2_menublock from another menu for which    */
  131.         /* we are now getting a message_MENUSDELETED, *after* we've     */
  132.         /* opened our dialog2 as a menu-window.                */
  133.         
  134.     Dialog2_CloseDialog( dialog2_menublock);
  135.     }
  136. return FALSE;
  137. }
  138.  
  139.  
  140.  
  141.  
  142.  
  143.  
  144. _DeskLib_SDLS_PtrFn(
  145.     static,
  146.     BOOL, 
  147.     Dialog2__OKCancelHandler( event_pollblock *event, void *reference)
  148.     )
  149. /*static BOOL    Dialog2__OKCancelHandler( event_pollblock *event, void *reference)*/
  150. /* Handler for click on OK or Cancel buttons.    */
  151. /* cc warns about extern ... not declared in header in SDLS compiles    */
  152. {
  153. dialog2_block *dialog2 = (dialog2_block *) reference;
  154.  
  155. if ( dialog2->flags.data.type == dialog2_type_CLOSED)    {
  156.     Error_ReportFatalInternal( 1, error_PLACE "Click for closed dialog2");
  157.     }
  158.  
  159. if ( dialog2->okfn && event->data.mouse.icon == dialog2->flags.data.okbutton)
  160.     dialog2->okfn( dialog2);
  161.     
  162.  
  163. if    ( 
  164.     event->data.mouse.button.data.select
  165.     &&
  166.         (
  167.            event->data.mouse.icon == dialog2->flags.data.okbutton
  168.         || event->data.mouse.icon == dialog2->flags.data.cancelbutton
  169.         )
  170.     )
  171.     {
  172.     Dialog2_CloseDialog( dialog2);
  173.     }
  174.  
  175. return FALSE;
  176. }
  177.  
  178.  
  179. _DeskLib_SDLS_PtrFn(
  180.     static,
  181.     BOOL, 
  182.     Dialog2__CloseHandler( event_pollblock *event, void *reference)
  183.     )
  184. /*static BOOL    Dialog2__CloseHandler( event_pollblock *event, void *reference)*/
  185. /* Handler for event_CLOSE.    */
  186. /* cc warns about extern ... not declared in header in SDLS compiles    */
  187. {
  188. UNUSED( event);
  189. Dialog2_CloseDialog( (dialog2_block *) reference);
  190. return FALSE;
  191. }
  192.  
  193.  
  194.  
  195.  
  196.  
  197. #define keycode_RETURN    13
  198. #define keycode_ESCAPE    0x1B
  199.  
  200. _DeskLib_SDLS_PtrFn(
  201.     static,
  202.     BOOL, 
  203.     Dialog2__KeyHandler( event_pollblock *event, void *reference)
  204.     )
  205. /*static BOOL    Dialog2__KeyHandler( event_pollblock *event, void *reference)*/
  206.  
  207. /* This sends our application an event_CLICK on the ok/cancel button    */
  208. /* when Return/Escape is pressed in the dialog box. Would be better to     */
  209. /* have an Event_FakeEvent function or something...            */
  210. /* cc warns about extern ... not declared in header in SDLS compiles    */
  211. {
  212. dialog2_block *dialog2 = (dialog2_block *) reference;
  213.  
  214. if ( dialog2->flags.data.type == dialog2_type_CLOSED)    {
  215.     Error_ReportFatalInternal( 1, error_PLACE "Click for closed dialog2");
  216.     }
  217.  
  218. if ( event->data.key.code == keycode_RETURN && dialog2->flags.data.okbutton != -1)    {
  219.     event_data    clickeventdata;
  220.     clickeventdata.mouse.button.value    = 0;
  221.     clickeventdata.mouse.button.data.select    = TRUE;
  222.     clickeventdata.mouse.window        = dialog2->window;
  223.     clickeventdata.mouse.icon        = dialog2->flags.data.okbutton;
  224.     Wimp_SendMessage( 
  225.         event_CLICK, 
  226.         (message_block *) &clickeventdata, 
  227.         event_taskhandle,             /* Us    */
  228.         dialog2->flags.data.okbutton
  229.         );
  230.     return TRUE;
  231.     }
  232.  
  233. else if ( event->data.key.code == keycode_ESCAPE && dialog2->flags.data.cancelbutton != -1)    {
  234.     event_data    clickeventdata;
  235.     clickeventdata.mouse.button.value    = 0;
  236.     clickeventdata.mouse.button.data.select    = TRUE;
  237.     clickeventdata.mouse.window        = dialog2->window;
  238.     clickeventdata.mouse.icon        = dialog2->flags.data.cancelbutton;
  239.     Wimp_SendMessage( 
  240.         event_CLICK, 
  241.         (message_block *) &clickeventdata, 
  242.         event_taskhandle,             /* Us    */
  243.         dialog2->flags.data.cancelbutton
  244.         );
  245.     return TRUE;
  246.     }
  247.  
  248. else Wimp_ProcessKey( event->data.key.code);
  249.  
  250. return FALSE;
  251. }
  252.  
  253.  
  254.  
  255.  
  256.  
  257.  
  258.  
  259.  
  260. static void    Dialog2__ClaimOrReleaseStandardHandlers( 
  261.     event_claimorreleasefn    fn, 
  262.     dialog2_block        *dialog2
  263.     )
  264.     /* This calls Event_Claim/Release for all the     */
  265.     /* events in which we are interested in.    */
  266.     /* Using the same function for claiming and     */
  267.     /* releasing events ensures we don't leave any    */
  268.     /* claims active that we don't use.        */
  269. {
  270. fn( event_OPEN,  dialog2->window, event_ANY, Handler_OpenWindow,    dialog2);
  271. fn(    event_CLOSE, dialog2->window, event_ANY, 
  272.     _DeskLib_SDLS_dllEntry( Dialog2__CloseHandler), 
  273.     dialog2
  274.     );
  275.  
  276. if ( dialog2->flags.data.okbutton != -1 || dialog2->flags.data.cancelbutton != -1)    {
  277.     fn(    event_KEY, dialog2->window, event_ANY, 
  278.         _DeskLib_SDLS_dllEntry( Dialog2__KeyHandler),   
  279.         dialog2
  280.         );
  281.     fn(    event_CLICK, dialog2->window, event_ANY, 
  282.         _DeskLib_SDLS_dllEntry( Dialog2__OKCancelHandler), 
  283.         dialog2
  284.         );
  285.     /* Make this icon-unspecific so that the application will get clicks first.    */
  286.     }
  287.  
  288. if ( dialog2->flags.data.type == dialog2_type_MENU
  289. ||   dialog2->flags.data.type == dialog2_type_MENULEAF
  290. )    {
  291.     fn(    event_USERMESSAGE, event_ANY, event_ANY, 
  292.         _DeskLib_SDLS_dllEntry( Dialog2__MenusDeletedHandler), 
  293.         NULL      
  294.         );
  295.         /* Closes the dialog2 if the menu is closed by Escape or a     */
  296.         /* click outside the menu.                    */
  297.         /* NB this won't work with RO2 - the dialog2 won't be closed    */
  298.         /* until the next dialog2 is opened as a menu.            */
  299.     }
  300.  
  301. }
  302.  
  303.  
  304.  
  305.  
  306.  
  307.  
  308.  
  309.  
  310.  
  311. void    Dialog2__CommonOpenCode( dialog2_block *dialog2)
  312. {
  313. Dialog2_EnsureWindowHandle( dialog2);
  314. Dialog2__ClaimOrReleaseStandardHandlers( Event_Claim, dialog2);
  315.  
  316. if (dialog2->openfn)    dialog2->openfn( dialog2);
  317.     /* Call this after 'Dialog2__ClaimOrReleaseStandardHandlers' 
  318.     so that any events claimed inside 'openfn' will
  319.     get sent to the application's code first.
  320.     */
  321.  
  322. }
  323.  
  324.  
  325.  
  326. void    Dialog2__CommonOpenMenuCode( dialog2_block *dialog2)
  327. {
  328. if ( dialog2_menublock)    {    /* Need to close the existing menu-dialog box.    */
  329.     if ( dialog2_menublock == dialog2)
  330.         Dialog2__CloseDialogInternal( dialog2_menublock, FALSE, FALSE);
  331.             /* This dialog is being re-opened, so don't delete the    */
  332.             /* window as we will only re-open it anyway.        */
  333.             
  334.     else    Dialog2__CloseDialogInternal( dialog2_menublock, FALSE, TRUE);
  335.     }
  336.  
  337. dialog2_menublock = dialog2;
  338.  
  339. }
  340.  
  341.  
  342.  
  343.  
  344.  
  345.  
  346.  
  347.  
  348.  
  349.  
  350.  
  351.  
  352.  
  353.